checkGBMModel <- function(myGBM.h2o, myGBM.r, h2oTest, RTest) {
  #Check GBM model against R
  Log.info("MSE by tree in H2O:")

  #The scoring history only shows scored trees - need to set score_each_iteration to TRUE if this test is to be re-enabled
  #expect_true(length(myGBM.h2o@model$scoring_history$training_MSE) == n.trees)

  Log.info("Gaussian Deviance by tree in R (i.e. the per tree 'train error'): \n")
  print(myGBM.r$train.error)
  #Log.info("Expect these to be close... mean of the absolute differences is < .5, and sd < 0.1")
  #errDiff <- abs(myGBM.r$train.error - myGBM.h2o@model$err)
  #Log.info(cat("Mean of the absolute difference is: ", mean(errDiff)))
  #Log.info(cat("Standard Deviation of the absolute difference is: ", sd(errDiff)))
  #expect_true(mean(errDiff) < 0.5)
  #expect_true(sd(errDiff) < 0.1)

  # Compare GBM models on out-of-sample data
  Log.info("Uploading GBM testing data...")
  ecologyTest.hex <- h2oTest
  ecologyTest.data <- RTest
  actual <- ecologyTest.data[,1]
  Log.info("Performing the predictions on h2o GBM model: ")

  # TODO: Building CM in R instead of in H2O
  h2ogbm.predict <- predict(myGBM.h2o, ecologyTest.hex)
  #h2o.preds <- head(h2ogbm.predict,nrow(h2ogbm.predict))[,1]
  h2o.preds <- as.data.frame(h2ogbm.predict)[,1]
  h2oCM <- table(actual,h2o.preds)
  Log.info("H2O CM is: \n")
  print(h2oCM)
  Log.info("Performing the predictions of R GBM model: ")
  R.preds <- ifelse(predict.gbm(myGBM.r, ecologyTest.data,n.trees=n.trees,type="response") < 0.5, 0,1)
  Log.info("R CM is: \n")
  RCM <- table(actual,R.preds)
  print(RCM)
  Log.info("Compare AUC from R and H2O:\n")
  Log.info("H2O AUC: ")
  print(gbm.roc.area(actual,h2o.preds))
  Log.info("R AUC: ")
  print(gbm.roc.area(actual,R.preds))
}

# Function call for R sided cross validation of h2o objects
h2o.gbm.cv <- function(x, y, training_frame, nfolds = 2,
           #AUTOGENERATED params
           model_id,
           distribution = c("bernoulli"),
           ntrees = 50,
           max_depth = 5,
           min_rows = 10,
           learn_rate = 0.1,
           nbins = 20,
           variable_importance = FALSE,
           balance_classes = FALSE,
           max_after_balance_size = 1,
           seed
           )
{
  env <- parent.frame()
  parms <- lapply(as.list(match.call()[-1L]), eval, env)
  parms$nfolds <- NULL

  do.call("h2o.crossValidate", list(model.type = 'gbm', nfolds = nfolds, params = parms))
}

# general xval utility
h2o.crossValidate <- function(model, nfolds, model.type = c("gbm", "glm", "deeplearning"), params, strategy = c("mod1", "random"), ...)
{
  output <- data.frame()

  if( nfolds < 2 ) stop("`nfolds` must be greater than or equal to 2")
  if( missing(model) & missing(model.type) ) stop("must declare `model` or `model.type`")
  else if( missing(model) )
  {
    if(model.type == "gbm") model.type = "h2o.gbm"
    else if(model.type == "glm") model.type = "h2o.glm"
    else if(model.type == "deeplearning") model.type = "h2o.deeplearning"

    model <- do.call(model.type, c(params))
  }
  output[1, "fold_num"] <- -1
  output[1, "model_key"] <- model@model_id
  # output[1, "model"] <- model@model$mse_valid

  data <- params$training_frame
  data <- eval(data)
  data.len <- nrow(data)

  # nfold_vec <- h2o.sample(fr, 1:nfolds)
  nfold_vec <- sample(rep(1:nfolds, length.out = data.len), data.len)

  fnum_id <- as.h2o(nfold_vec)
  fnum_id <- h2o.cbind(fnum_id, data)

  xval <- lapply(1:nfolds, function(i) {
      params$training_frame   <- data[fnum_id$x != i, ]
      params$validation_frame <- data[fnum_id$x == i, ]
      fold <- do.call(model.type, c(params))
      output[(i+1), "fold_num"] <<- i - 1
      output[(i+1), "model_key"] <<- fold@model_id
      # output[(i+1), "cv_err"] <<- mean(as.vector(fold@model$mse_valid))
      fold
    })
  print(output)

  model
}
